<script lang="ts">
    import {bem} from "@/common/util";
    import mixin from "@/uni_modules/u-tools/mixin/mixin";
    import mpMixin from "@/uni_modules/u-tools/mixin/mpMixin";
    import props from "./props";
    import UImage from "@/uni_modules/u-image/components/u-image/u-image.vue";
    import UIcon from "@/uni_modules/u-icon/components/u-icon/u-icon.vue";
    import ULoadingIcon from "@/uni_modules/u-loading-icon/components/u-loading-icon/u-loading-icon.vue";

    export default {
        name: "u-button",
        // 组件
        components: {UIcon, UImage, ULoadingIcon},
        // 混合
        mixins: [props, mixin, mpMixin],
        // 事件
        emits: [
            "click",
            "openTypeGetPhoneNumber",
            "openTypeGetUserInfo",
            "openTypeError",
            "openTypeLaunchApp",
            "openTypeContact",
            "openTypeChooseAvatar",
            "openTypeAddGroupApp",
            "openTypeChooseAddress",
            "openTypeChooseInvoiceTitle",
            "openTypeSubscribe",
            "openTypeLogin",
            "openTypeOpenSetting",
            "openTypeAgreePrivacyAuthorization",
            "openTypeIm"
        ],
        // 数据
        data()
        {
            return {};
        },
        // 计算属性
        computed: {
            // 生成bem风格的类名
            bemClass(): string
            {
                return bem("button", [
                    this.size,
                    this.shape,
                    this.border ? "border" : "",
                    this.plain ? "plain" : "",
                    this.disabled ? "disabled" : "",
                    this.loading ? "loading" : "",
                    this.type,
                    this.shape === "square" && SizeTypeMap.includes(this.radius.toString()) ? `radius-${this.radius}` : ""
                ]);
            },
            // 获取文字大小
            getFontSize(): number
            {
                let fontSize = 14;

                // 根据size属性，设置文字大小
                if (this.size === "large")
                {
                    fontSize = 16;
                }
                else if (this.size === "normal")
                {
                    fontSize = 14;
                }
                else if (this.size === "small")
                {
                    fontSize = 12;
                }
                else if (this.size === "mini")
                {
                    fontSize = 10;
                }

                return fontSize;
            },
            // 边框或背景色
            baseColor(): Record<string, any>
            {
                let style: Record<string, string> = {};

                const color = this.backgroundColor;

                // 判断是否存在自定义背景色
                if (color)
                {
                    // 镂空样式
                    if (this.plain)
                    {
                        // 判断是否为渐变
                        if (color.includes("gradient"))
                        {
                            style.borderImage = `${color} 1`;
                        }
                        else
                        {
                            style.borderColor = color;
                        }
                    }
                    else
                    {
                        // 判断是否为渐变
                        if (color.includes("gradient"))
                        {
                            style.backgroundImage = color;
                            style.borderImage = `${color} 1`;
                        }
                        else
                        {
                            style.backgroundColor = color;
                            style.borderColor = color;
                        }
                    }
                }

                return style;
            },
            // 文字颜色
            fontColor(): Record<string, any>
            {
                let style: Record<string, string> = {};

                // 判断是否存在自定义背景色
                if (this.color)
                {
                    style.color = this.color;
                }

                return style;
            },
            // 图标颜色
            iconfontColor(): string
            {
                if (this.iconColor)
                {
                    return this.iconColor;
                }
                else
                {
                    // 判断是否为镂空按钮
                    if (this.plain)
                    {
                        return this.color ? this.color : this.type === "info" ? "#323233" : this.$u.color[this.type] ? this.$u.color[this.type] : "#fff";
                    }
                    else
                    {
                        return this.color ? this.color : this.type === "info" ? "#323233" : "#fff";
                    }
                }
            },
            // 图标大小
            iconfontSize(): string
            {
                let iconfontSize = "";

                if (this.iconSize)
                {
                    iconfontSize = this.$u.unit(this.iconSize);
                }
                else
                {
                    iconfontSize = this.$u.unit(this.getFontSize * 1.35);
                }

                return iconfontSize;
            },
            // 图片尺寸
            iconImageSize(): {width: string; height: string}
            {
                const size: {width: string; height: string} = {
                    width: "",
                    height: ""
                };

                if (this.iconImageWidth)
                {
                    size.width = this.$u.unit(this.iconImageWidth);
                }
                else
                {
                    size.width = this.$u.unit(this.getFontSize * 1.35);
                }

                if (this.iconImageHeight)
                {
                    size.height = this.$u.unit(this.iconImageHeight);
                }
                else
                {
                    size.height = this.$u.unit(this.getFontSize * 1.35);
                }

                return size;
            },
            // 获取按钮圆角
            getRadius(): string
            {
                let radius = "";

                // 判断是否为方形按钮
                if (this.shape === "square")
                {
                    // 判断是否为指定大小的圆角
                    if (!SizeTypeMap.includes(this.radius.toString()))
                    {
                        radius = this.$u.unit(this.radius);
                    }
                }

                return radius;
            }
        },
        // 方法
        methods: {
            // 点击事件
            clickHandler(event: Record<string, any>): void
            {
                this.$emit("click", {event});

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 开放能力-获取用户手机号回调,open-type="getPhoneNumber", 微信、支付宝、百度、字节、快手、京东小程序
            getPhoneNumberHandler(data: any): void
            {
                this.$emit("openTypeGetPhoneNumber", data);
            },
            // 开放能力-获取用户信息回调,open-type="getUserInfo", 微信、QQ、百度、快手、京东小程序
            getUserInfoHandler(data: any): void
            {
                this.$emit("openTypeGetUserInfo", data);
            },
            // 开放能力-获取开放能力时发生错误回调,open-type="launchApp",微信、QQ、快手、京东小程序
            getOpenTypeErrorHandler(error: any): void
            {
                this.$emit("openTypeError", error);
            },
            // 开放能力-在打开授权设置页并关闭后回调,open-type="openSetting", 微信、QQ、百度、快手、京东小程序
            openSettingHandler(data: any): void
            {
                this.$emit("openTypeOpenSetting", data);
            },
            // 开放能力-从小程序打开APP成功的回调,open-type="launchApp",微信、QQ、快手、京东小程序
            launchAppHandler(data: any): void
            {
                this.$emit("openTypeLaunchApp", data);
            },
            // 开放能力-客服消息回调,open-type="contact",微信、QQ、百度、快手小程序
            contactHandler(data: any): void
            {
                this.$emit("openTypeContact", data);
            },
            // 开放能力-获取用户头像回调,open-type="chooseAvatar",微信小程序
            chooseAvatarHandler(data: any): void
            {
                this.$emit("openTypeChooseAvatar", data);
            },
            // 开放能力-同意隐私协议
            agreePrivacyAuthorizationHandler(): void
            {
                this.$emit("openTypeAgreePrivacyAuthorization", error);
            },
            // 开放能力-添加群应用的回调,open-type="addGroupApp",QQ小程序
            addGroupAppHandler(data: any): void
            {
                this.$emit("openTypeAddGroupApp", data);
            },
            // 开放能力-调起用户编辑并选择收货地址的回调,open-type="chooseAddress",百度小程序
            chooseAddressHandler(data: any): void
            {
                this.$emit("openTypeChooseAddress", data);
            },
            // 开放能力-用户选择发票抬头的回调,open-type="chooseInvoiceTitle",百度小程序
            chooseInvoiceTitleHandler(data: any): void
            {
                this.$emit("openTypeChooseInvoiceTitle", data);
            },
            // 开放能力-订阅消息授权回调,open-type="subscribe",百度小程序
            subscribeHandler(data: any): void
            {
                this.$emit("openTypeSubscribe", data);
            },
            // 开放能力-登录回调,open-type="login",百度小程序
            loginHandler(data: any): void
            {
                this.$emit("openTypeLogin", data);
            },
            // 开放能力-监听跳转IM的成功回调,open-type="im",抖音小程序
            imHandler(data: any): void
            {
                this.$emit("openTypeIm", data);
            }
        }
    };
</script>

<template>
    <view
        :class="customClass"
        :style="customStyle"
        class="u-button-warp"
    >
        <button
            :class="bemClass"
            :disabled="disabled"
            :form-type="formType"
            :hover-class="!disabled && !loading ? 'u-button-active' : ''"
            :hover-start-time="hoverStartTime"
            :hover-stay-time="hoverStayTime"
            :open-type="openType"
            :style="[
                baseColor,
                fontColor,
                {'--custom-button-radius': getRadius}
            ]"
            @addgroupapp="addGroupAppHandler"
            @agreeprivacyauthorization="agreePrivacyAuthorizationHandler"
            @chooseaddress="chooseAddressHandler"
            @chooseavatar="chooseAvatarHandler"
            @chooseinvoicetitle="chooseInvoiceTitleHandler"
            @click="clickHandler"
            @contact="contactHandler"
            @error="getOpenTypeErrorHandler"
            @getphonenumber="getPhoneNumberHandler"
            @getuserinfo="getUserInfoHandler"
            @im="imHandler"
            @launchapp="launchAppHandler"
            @login="loginHandler"
            @opensetting="openSettingHandler"
            @subscribe="subscribeHandler"
        >
            <template v-if="loading">
                <!-- Loading -->
                <view
                    :style="[
                        {marginRight: $u.unit(loadingSpacing)}
                    ]"
                    class="loading"
                >
                    <u-loading-icon
                        :size="loadingSize"
                        :mode="loadingMode"
                        :duration="loadingDuration"
                    />
                </view>
                <!-- //Loading -->

                <!-- 文本 -->
                <text
                    :style="[
                        {
                            'font-size': `${getFontSize}px`
                        },
                        fontColor
                    ]"
                    class="text"
                >
                    {{ loadingText || text }}
                </text>
                <!-- //文本 -->
            </template>

            <template v-else>
                <!-- 图标 -->
                <view
                    v-if="icon"
                    :style="{'margin-right': `${$u.unit(iconSpacing)}`}"
                    class="icon"
                >
                    <u-icon
                        :color="iconfontColor"
                        :icon="icon"
                        :size="iconfontSize"
                    />
                </view>
                <!-- //图标 -->

                <!-- 图片 -->
                <view
                    v-if="iconImage"
                    :style="{'width': iconImageSize.width, 'height': iconImageSize.height, 'margin-right': $u.unit(iconImageSpacing)}"
                    class="left-image"
                >
                    <u-image
                        :src="iconImage"
                        v-bind="$attrs"
                    />
                </view>
                <!-- //图片 -->

                <!-- 文本 -->
                <text
                    :style="[
                        {
                            'font-size': `${getFontSize}px`
                        },
                        fontColor
                    ]"
                    class="text"
                >
                    {{ text }}
                </text>
                <!-- //文本 -->
            </template>
        </button>
    </view>
</template>

<style lang="scss" scoped>
    // large
    $u-button-large-height: $size-large !default;
    $u-button-large-padding: 0 15px !default;

    // normal
    $u-button-normal-height: $size-normal !default;
    $u-button-normal-padding: 0 12px !default;

    // small
    $u-button-small-height: $size-small !default;
    $u-button-small-padding: 0 8px !default;

    // mini
    $u-button-mini-height: $size-mini !default;
    $u-button-mini-padding: 0 6px !default;

    // 半圆按钮
    $u-button-circle-border-radius: 100px !default;

    // 信息提示
    $u-button-info-background-color: #fff !default;
    $u-button-info-border-color: #ebedf0 !default;
    $u-button-info-color: #323233 !default;
    $u-button-info-active-background-color: $theme-info-light !default;

    // 主要提示
    $u-button-primary-background-color: $theme-primary !default;
    $u-button-primary-border-color: $theme-primary !default;
    $u-button-primary-color: #fff !default;
    $u-button-primary-active-background-color: $theme-primary-dark !default;

    // 成功提示
    $u-button-success-background-color: $theme-success !default;
    $u-button-success-border-color: $theme-success !default;
    $u-button-success-color: #fff !default;
    $u-button-success-active-background-color: $theme-success-dark !default;

    // 错误提示
    $u-button-error-background-color: $theme-error !default;
    $u-button-error-border-color: $theme-error !default;
    $u-button-error-color: #fff !default;
    $u-button-error-active-background-color: $theme-error-dark !default;

    // 警告提示
    $u-button-warning-background-color: $theme-warning !default;
    $u-button-warning-border-color: $theme-warning !default;
    $u-button-warning-color: #fff !default;
    $u-button-warning-active-background-color: $theme-warning-dark !default;

    // 镂空背景
    $u-button-plain-background-color: #fff !default;

    // 按钮
    .u-button
    {
        font-size: inherit;
        line-height: inherit;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0;
        cursor: pointer;
        color: inherit;
        background-color: transparent;

        // 图标
        .icon
        {
            margin-right: 4px;
        }

        // 文本
        .text
        {
            line-height: 20px;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
        }

        // large
        &-large
        {
            height: $u-button-large-height;
            padding: $u-button-large-padding;
        }

        // normal
        &-normal
        {
            height: $u-button-normal-height;
            padding: $u-button-normal-padding;
        }

        // small
        &-small
        {
            height: $u-button-small-height;
            padding: $u-button-small-padding;
        }

        // mini
        &-mini
        {
            height: $u-button-mini-height;
            padding: $u-button-mini-padding;
        }

        // 边框
        &-border
        {
            border-width: 1px;
            border-style: solid;
        }

        // 圆角按钮
        &-square
        {
            border-radius: var(--custom-button-radius);

            // 超小尺寸圆角
            &.u-button-radius-mini
            {
                border-radius: $border-radius-mini;
            }

            // 小尺寸圆角
            &.u-button-radius-small
            {
                border-radius: $border-radius-small;
            }

            // 普通尺寸圆角
            &.u-button-radius-normal
            {
                border-radius: $border-radius-normal;
            }

            // 大尺寸圆角
            &.u-button-radius-large
            {
                border-radius: $border-radius-large;
            }
        }

        // 半圆按钮
        &-circle
        {
            border-radius: $u-button-circle-border-radius;
        }

        // 信息提示
        &-info
        {
            border-color: $u-button-info-border-color;
            background-image: var(--u-button-background-color, $u-button-info-background-color);

            // 文本
            .text
            {
                color: $u-button-info-color;
            }

            // 镂空按钮
            &.u-button-plain
            {
                background-color: $u-button-plain-background-color;

                // 文本
                .text
                {
                    color: $u-button-info-color;
                }
            }
        }

        // 成功提示
        &-success
        {
            border-color: $u-button-success-border-color;
            background-color: $u-button-success-background-color;

            // 文本
            .text
            {
                color: $u-button-success-color;
            }

            // 镂空按钮
            &.u-button-plain
            {
                background-color: $u-button-plain-background-color;

                // 文本
                .text
                {
                    color: $u-button-success-border-color;
                }
            }
        }

        // 错误提示
        &-error
        {
            border-color: $u-button-error-border-color;
            background-color: $u-button-error-background-color;

            // 文本
            .text
            {
                color: $u-button-error-color;
            }

            // 镂空按钮
            &.u-button-plain
            {
                background-color: $u-button-plain-background-color;

                // 文本
                .text
                {
                    color: $u-button-error-border-color;
                }
            }
        }

        // 警告提示
        &-warning
        {
            border-color: $u-button-warning-border-color;
            background-color: $u-button-warning-background-color;

            // 文本
            .text
            {
                color: $u-button-error-color;
            }

            // 镂空按钮
            &.u-button-plain
            {
                background-color: $u-button-plain-background-color;

                // 文本
                .text
                {
                    color: $u-button-warning-border-color;
                }
            }
        }

        // 主要提示
        &-primary
        {
            border-color: $u-button-primary-border-color;
            background-color: $u-button-primary-background-color;

            // 文本
            .text
            {
                color: $u-button-error-color;
            }

            // 镂空按钮
            &.u-button-plain
            {
                background-color: $u-button-plain-background-color;

                // 文本
                .text
                {
                    color: $u-button-primary-border-color;
                }
            }
        }

        // 禁用
        &-disabled
        {
            cursor: no-drop;
            user-select: none;
            opacity: 0.5;
        }

        // loading
        &-loading
        {
            cursor: no-drop;
        }

        // loading图标
        .loading
        {
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }

        &:after
        {
            border: none;
        }
    }

    // 激活
    .u-button-active
    {
        opacity: 0.68;
    }
</style>